from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker

from app.config import DB
from app.database.models import Base


def make_connection_string(db: DB, async_fallback: bool = False) -> str:
    result = f"mysql+aiomysql://{db.user}:{db.password}@{db.host}:{db.port}/{db.name}"
    if async_fallback:
        result += "?async_fallback=True"
    return result


async def sa_sessionmaker(db: DB, echo: bool = False) -> sessionmaker:
    """
    Make sessionmaker
    :param db: DB config
    :param echo: Turn on/off sqlalchemy echo
    :return: sessionmaker
    :rtype: sqlalchemy.orm.sessionmaker
    """
    engine = create_async_engine(
        make_connection_string(db), echo=echo, connect_args={"connect_timeout": 60}
    )

    # async with engine.begin() as conn:
    #     await conn.run_sync(Base.metadata.create_all)

    return sessionmaker(
        bind=engine,
        expire_on_commit=False,
        class_=AsyncSession,
        future=True,
        autoflush=False,
    )
